#include "QROHost_P.h"

bool QROHost::Private::onOccupyObject(RemoteInterfaceSourceImp* src,quint32 target){
    //检查一下是否有客户端已经占领了该对象
    for(auto i:m_channels)
    {
        if(i.second->channel->ownedObjs() == target)
        {
            return false;
        }
    }

    src->setOwnedObjs(target);
    auto obj = m_objectDataMap[target]->obj;
    _Q->objectOccupied(obj);

    return true;
}

bool QROHost::Private::onReleaseObject(RemoteInterfaceSourceImp* src)
{
    auto ownedId =src->ownedObjs();
    if(ownedId)
    {
        src->setOwnedObjs(NullID);
        auto obj = m_objectDataMap[ownedId]->obj;
        _Q->objectReleased(obj);
    }

    return false;
}

ChannelID QROHost::Private::belongsTo(ObjectID obj){
    //一个对象，当它的最近祖先属于某个客户端时，它就属于某个客户端
    QHash<ObjectID,ChannelID> clientSet;

    for(auto i :m_channels)
    {
        auto channel = i.second->channel;
        auto owned = channel->ownedObjs();
        if(owned)
        {
            clientSet[owned] = channel->id();
        }
    }

    if(clientSet.empty())//没有任何客户端占领任何对象，直接返回空
    {
        return NullChannel;
    }

    auto data = m_objectDataMap.value(obj);

    if(!data) return NullChannel;

    auto temp = data->obj;

    while (temp) {
        auto id = m_objectIdMap.value(temp,NullID);
        if(id)
        {
            if(clientSet.contains(id))
            {
                return clientSet[id];
            }
        }

        temp = temp->parent();
    }
    return NullChannel;
}

static bool ReleaseImp(QROHost::Private* _P,QObject* target){
    if(!_P->m_objectIdMap.contains(target))
    {
        return false;
    }
    auto targetId =_P->m_objectIdMap[target];
    for(auto i:_P->m_channels)
    {
        if(i.second->channel->ownedObjs() == targetId)
        {
            i.second->channel->setOwnedObjs(NullID);
            _P->_Q->objectReleased(target);
            return true;
        }
    }

    return false;
}

void QROHost::Private::onOccupyObject(QObject* target){
    ReleaseImp(this,target);
}

void QROHost::Private::onReleaseObject(QObject* target)
{
    ReleaseImp(this,target);
}
